scrapy爬取上海链家网35000条在租房信息并导入数据库

本文在有些需要解释说明的地方引用了知乎文章屌丝想买房……Scrapy入门教程

本篇教程中将按照下列五步实现标题所述目标:

1、创建一个Scrapy项目

本篇建议安装Anaconda3,Anaconda可以很方便地解决多版本python并存、切换以及各种第三方包安装问题。Anaconda利用工具/命令conda来进行package和environment的管理,并且已经包含了Python和相关的配套工具。

  • 1、新建项目: scrapy startproject lianjia
  • 2、切换目录:cd lianjia
  • 3、新建爬虫:scrapy genspider Ljia sh.lianjia.com/zufang

工程文件说明:
scrapy.cfg 记录项目的配置信息
items.py 存放爬取完数据的模板,用于结构化数据
pipelines 数据处理行为,比如结构化的数据,存放到数据库持久化等等
settings.py 配置文件,比如递归的层数、并发数,延迟下载等
spiders 真正干活的爬虫目录,对网页的数据清洗

2、定义提取的Item

Item是我们要爬取数据的模板,因此我们应该先编辑lianjia/lianjia下的items文件
观察我们要爬取的在租房示例图,首先想好你要爬取哪些关键信息


在租房示例图

我定义的目标提取字段比较详细(也可以说比较啰嗦),字段含义参考代码注释


# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy


class LianjiaItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title = scrapy.Field()      #房间标题,例如:申金大厦,好楼层,钥匙在链家,链家好房
    roomType = scrapy.Field()   #房间类型,几室几厅
    roomName = scrapy.Field()   #房间名,例如:申金大厦
    roomPrice = scrapy.Field()  #价格,按月为单位
    roomStatus = scrapy.Field() #房间状态,例如:随时看房
    roomDate = scrapy.Field()   #房间上架日期,例如:2017.08.06
    areaB = scrapy.Field()      #区域   例如:浦东,黄浦
    street = scrapy.Field()     #街道,例如:距离5号线金平路站794米

3、编写爬取网站的spider并提取Item

网页解析

租房信息
网页源码

可以看到网页元素还是很好抽取的,但是我们要先做一些准备工作

  • 1、把setting.py里面的ROBOT协议尊守改为False,不修改爬不了任何数据).
settings.py
  • 2、添加浏览器代理
取消这块代码的注释并添加浏览器的代理
  • 3、取消注释
image.png

以下代码使用xpath提取目标字段,xpath是抽取HTML元素最为便捷和快捷的方式,关于xpath的使用参考xpath语法


# -*- coding: utf-8 -*-
import scrapy
import re
from lianjia.items import LianjiaItem

class LjiaSpider(scrapy.Spider):
    name = 'Ljia'
    allowed_domains = ['https://sh.lianjia.com/zufang']
    start_urls = ['https://sh.lianjia.com/zufang']
    

    def parse(self, response):
        for i in response.xpath('.//li/div[@class="info-panel"]'):
            item = LianjiaItem()
            item['title'] = i.xpath('.//h2/a/@title').extract_first()
            item['roomName'] = i.xpath('.//div[@class="where"]/a/span/text()').extract_first()
            item['roomType'] = i.xpath('.//div[@class="where"]/span/text()').extract_first().rstrip(' &nbsp')
            roomDesc = i.xpath('.//div[@class="con"]').extract_first()
            item['roomPrice'] = i.xpath('.//div[@class="price"]/span/text()').extract_first()
            item['roomStatus'] = i.xpath('.//span[@class="anytime-ex"]/span/text()').extract_first()
            item['roomDate'] = i.xpath('.//div[@class="col-3"]/div[@class="price-pre"]/text()').extract_first().rstrip('7\n\t\t\t\t\t\t\t上架')
            item['areaB'] = str(i.xpath('.//div[@class="con"]/a/text()').extract()[0])
            item['street'] = i.xpath('.//span[@class="fang-subway-ex"]/span/text()').extract_first()
            yield item
        temp_url = response.xpath('//a[@gahref="results_next_page"]/@href').extract()[0]
        if temp_url:
            url = 'https://sh.lianjia.com' + temp_url
        yield scrapy.Request(url=url, callback=self.parse, dont_filter=True)

注释:extract_first()方法用来序列化抽取到的网页元素,dont_filter字段用于避免服务器把我们的爬虫url做重定向

4、编写Item PipeLine来存储提取到的Item(即数据)

/lianjia/lianjia/pipelines 文件

import pymysql 

class LianjiaPipeline(object):
    
    def __init__(self):
        self.conn = pymysql.connect(host='localhost', user='root', passwd='****', \
                                   db='***', charset='utf8')
        self.cur = self.conn.cursor()
        
    def process_item(self, item, spider):
        
        title = item.get('title', 'N/A')
        roomType = item.get('roomType', 'N/A')
        roomName = item.get('roomName', 'N/A')
        #roomSize = item.get('roomSize', 'N/A')
        #roomDesc = item.get('roomDesc', 'N/A')
        roomPrice = item.get('roomPrice', 'N/A')
        roomStatus = item.get('roomStatus', 'N/A')
        roomDate = item.get('roomDate', 'N/A')
        areaB = item.get('areaB', 'N/A')
        street = item.get('street', 'N/A')
        
        sql = 'insert into lianjia(title, roomType, roomName, roomPrice, \
                roomStatus, roomDate, areaB, street) values(%s, %s, %s, %s, %s, %s, %s, %s)'
        self.cur.execute(sql, (title, roomType, roomName, roomPrice, roomStatus, roomDate,areaB, street))
        self.conn.commit()
        #return item
        
    def close_spider(self, spider):
        self.cur.close()
        self.conn.close()

注释:
1、安装pymysql包:pip install pymysql
2、self.cur(游标对象)用于对数据表操作,self.conn(数据库对象)用于提交对数据库的操作

5、让爬虫动起来

上面的爬虫工程已经准备好了,现在可以运行一下等待结果了

  • 初步调试阶段:
    先注释掉pipelines文件中的sql执行语句,执行命令scrapy crawl Ljia -o house.csv做初步调试,不着急导入数据库,在终端观察爬虫运行情况,若出现报错则查看错误信息进行故障排查,若爬取成功则打开lianjia目录下面的house.csv文件查看爬取结果
部分结果
  • 数据库导入阶段:
    若上面执行成功,则开始导入数据库,取消注释sql语句,执行命令scrapy crawl Ljia,在终端观察导入情况,若有报错,则排除问题,若成功写入, 则本次试验到此结束。若有数据库编码问题,可尝试自行解决。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容